package com.lelouch.service;

import com.google.common.collect.Lists;
import com.lelouch.bean.SysLog;
import com.lelouch.bean.SysLogWithBLOBs;
import com.lelouch.bean.SysRole;
import com.lelouch.bean.SysRoleAcl;
import com.lelouch.beans.LogType;
import com.lelouch.common.RequestHolder;
import com.lelouch.dao.SysAclMapper;
import com.lelouch.dao.SysLogMapper;
import com.lelouch.dao.SysRoleAclMapper;
import com.lelouch.dao.SysRoleMapper;
import com.lelouch.util.IpUtil;
import com.lelouch.util.JsonMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 角色权限关系服务
 *
 * @author lcy
 * @create 2018-06-23 10:57
 */
@Service
public class SysRoleAclService {

    @Autowired
    private SysRoleAclMapper sysRoleAclMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysLogMapper sysLogMapper;


    public void changeRoleAcls(int roleId, List<Integer> aclIdList) {
        List<Integer> oldAclIdList = sysRoleAclMapper.getAclIdsByRoleIdList(Lists.newArrayList(roleId));//todo
        if (aclIdList.size() == oldAclIdList.size()) {
            Set<Integer> newIdSet = aclIdList.stream().collect(Collectors.toSet());
            Set<Integer> oldIdSet = oldAclIdList.stream().collect(Collectors.toSet());
            newIdSet.removeAll(oldIdSet);
            if (CollectionUtils.isEmpty(newIdSet)) {
                return;
            }
        }
        updateRoleAcls(roleId, aclIdList);
        saveRoleAclLog(roleId,oldAclIdList,aclIdList);
    }

    @Transactional
    public void updateRoleAcls(int roleId, List<Integer> aclIdList) {
        sysRoleAclMapper.deleteByRoleId(roleId);//todo

        if (CollectionUtils.isEmpty(aclIdList)) {
            return;
        }
        List<SysRoleAcl> roleAclList = Lists.newArrayList();
        for (Integer aclId : aclIdList) {
            SysRoleAcl roleAcl = SysRoleAcl.builder().roleId(roleId).aclId(aclId).operator(RequestHolder.getUser().getUsername())
                    .operateIp(IpUtil.getRemoteIp(RequestHolder.getRequest())).operateTime(new Date()).build();
            roleAclList.add(roleAcl);
        }
        sysRoleAclMapper.batchInsert(roleAclList);//todo

    }


    public List<SysRole> getRoleListByAclId(Integer aclId) {
        List<Integer> roleIdList = sysRoleAclMapper.getRoleListByAclId(aclId);
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Lists.newArrayList();
        }
        return sysRoleMapper.getRoleListByIdList(roleIdList);
    }


    private void saveRoleAclLog(int roleId, List<Integer> before, List<Integer> after) {
        SysLogWithBLOBs sysLog = new SysLogWithBLOBs();
        sysLog.setType(LogType.TYPE_ROLE_ACL);
        sysLog.setTargetId(roleId);
        sysLog.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
        sysLog.setNewCalue(after == null ? "" : JsonMapper.obj2String(after));
        sysLog.setOperator(RequestHolder.getUser().getUsername());
        sysLog.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getRequest()));
        sysLog.setOperateTime(new Date());
        sysLog.setStatus(1);
        sysLogMapper.insertSelective(sysLog);
    }
}
